#include "Hash_SIGNAL.h"

HashMap* Funcsignal;
//Func = key : char * funcname ; value :  pFuncValue value;

pFuncValue gloabl;// 全局变量



void initFuncMap()
{
    Funcsignal = HashMapInit();// 初始化HashMap* Funcsignal;
    gloabl = malloc(sizeof(FuncValue));// 初始化pFuncValue gloabl;
        HashMap* Vars = HashMapInit();
        gloabl->attr = -1;
        gloabl->start = -1;
        gloabl->Vars = Vars;
        gloabl->Params = 0;
}

void insertFuncSignal(char* funcname, int attr, int start)
{
    pFuncValue FuncVal = malloc(sizeof(FuncValue));// 初始化参数的符号表
        HashMap* Vars = HashMapInit();
        FuncVal->attr = attr;
        FuncVal->start = start;
        FuncVal->Vars = Vars;
        FuncVal->Params = 0;
    HashMapPut(Funcsignal, funcname, FuncVal);
}

pVarsValue initpVarsValue(int attr1, int attr2, int dimcount, int* dim)
{
    pVarsValue VarsVal = malloc(sizeof(pVarsValue));
    VarsVal->attr1 = attr1;
    VarsVal->attr2 = attr2;
    VarsVal->dimcount = dimcount;
    if (0 == dimcount)//常量
    {
        return VarsVal;
    }
    else
    {
        /*
        List* dimtem = ListInit();
        for (size_t i = 0; i < dimcount; i++)
        {
            ListPushBack(dimtem, dim[i]);
        }
        VarsVal->dim = dimtem;
        */
        VarsVal->dim = dim;
        return VarsVal;
    }
    /*
    List* dimtem = ListInit();
    //List* values = ListInit();
    
    if (dimcount != 0)
    {//数组
        int sum = 1;
        for (size_t i = 0; i < dimcount; i++)
        {
            ListPushBack(dimtem, dim[i]);
            sum = sum * dim[i];
        }
        //越界检测用dim
        //1220不初始化数，只存放维度信息//1224存放0
        //符号表不用value3.4
        //注释掉报错？
        if(-1 != dim[0])
        {
            for (size_t i = 0; i < sum; i++)
            {
                ListPushBack(values, 0);
            }
        }
    }
    else
    {//非数组
        ListPushBack(dimtem, 0);
        ListPushBack(values, 0);
    }
    Vars->attr1 = attr1;
    Vars->attr2 = attr2;
    Vars->dim = dimtem;
    Vars->values = values;
    return Vars;
    */
}

void InsertVars(char* funcname, char* name, pVarsValue value)
{
    if (NULL == funcname)
    {
        HashMapPut(gloabl->Vars, name, value);
        gloabl->Params += 1;
    }
    else
    {
        pFuncValue FuncVal;
        FuncVal = HashMapGet(Funcsignal, funcname);
        HashMapPut(FuncVal->Vars, name, value);
        FuncVal->Params += 1;
    }
}


// -----------查询----------- // 错误反馈部分？

int getParamsNum(char* funcname)
{
    pFuncValue FuncVal;
    FuncVal = HashMapGet(Funcsignal, funcname);
    return FuncVal->Params;
}

pFuncValue getFuncValue(char name[])
{
    pFuncValue funcval;
    funcval = HashMapGet(Funcsignal, name);
    return funcval;
}

char* ijktooffset(char* funcname,int dimcount, int* dimijk, char* name)
{
    
    pFuncValue funcval;
    if (NULL == funcname)
    {
        funcval = gloabl;
    }
    else
    {
        funcval = getFuncValue(funcname);
    }
    pVarsValue VarsVal = HashMapGet(funcval->Vars, name);
    // 如果在函数中找不到，则就是在全局变量中
    if (NULL == VarsVal)
    {
        VarsVal = HashMapGet(gloabl->Vars, name);
    }
    
    
    //if (NULL == val){/*找不到变量报错*/}
    /*//配合VarsValue->List* dim 实现越界检查？
    unsigned int dimcount = ListSize(val->dim);
    void * getnum;
    int *pnumtem;
    int numtem;
    int *dimtem = malloc(sizeof(int)*dimcount);
    for (size_t i = 0; i < dimcount; i++)
    {
        dimtem[i] = 0;
    }
    for (size_t i = 1; i < dimcount; i++)
    {
        ListGetAt(val->dim, i, &getnum);
        pnumtem = getnum;
        numtem = pnumtem;
        for (size_t j = 0; j < i; j++)
        {
           int tem = (dimijk[j]) * numtem;
           dimtem[j] = (dimijk[j]) * numtem;
        }
    }
    释放dimtem
    */
    // dimtem 存储的是权重, 即该位上的1代表的偏移量,高位的权重等于低位的乘积
    int* dim =  VarsVal->dim;
    int* dimtem = malloc(sizeof(int)*dimcount);
    dimtem[dimcount - 1] = 1;// 最低一位的权重是1
    for (size_t i = dimcount - 2; -1 != i; i--)
    {
        dimtem[i] = dimtem[i+1] * dim[i+1];
    }

    int idx = 0;// 偏移量
    for (size_t i = 0; i < dimcount; i++)
    {
        idx = idx + dimijk[i]*dimtem[i];
    }
    //idx = idx + dimijk[dimcount-1];
    free(dimtem);
    // free(dimijk);// 释放否？

    // 转换偏移量为字符串 : name '#' 偏移量
    int i = idx;//idx为偏移量
    int j = i;
    int size = 1;
    for (i = i/10; i!=0; size++)
    {
        i = i/10;
    }
    char* temnum = malloc(sizeof(char)*(size));
    i=0;
    for (size_t z = 0; name[z] != 0; z++)
    {
        i++;
    }
    
    char* num = malloc(sizeof(char)*(size + i + 1 + 1));
    num[i] = '#';num[size + i + 1] = 0;
    //itoa(j,temnum ,10);
    sprintf(temnum, "%d",j);
    for (size_t z = 0; z < i; z++)
    {
        num[z] = name[z];
    }
    
    for (size_t z = i; z < size + i + 1; z++)
    {
        num[z+1] = temnum[z-i];
    }
    return num;
}


// -----------更改----------- // 优化部分?


// ---------下面是想法--------- //
/*
void putinfuncsignal(char funcname[], int startid, int attr1)
{
    
    HashMapPut(FuncIDName, start, funcname);
    pFuncValue funcvalue = initFuncValue(attr1, startid);
    HashMapPut(Funcsignal, funcname, funcvalue);
}
*/

// -----------旧代码----------- //
/*
旧代码
// 置入Func HASH表
void insertFunc(char* funcname, pFuncValue FuncVal)
{
    
}

pFuncValue initFuncValue(int attr, int start)
{
    HashMap* Vars = HashMapInit();
    pFuncValue func = malloc(sizeof(FuncValue));
        func->attr = attr;
        func->start = start;
        func->Vars = Vars;
    return func;
}

//int dimcount 维度的数量
//int dim[] 各个维度组成的一个数组
//int value[] 初始化好的（补全了0的）一个一维数组
//储存多个维度为二维以上数组的读取准备
pVarsValue initpVarsValue(int attr1, int attr2, int dimcount, int dim[])
{
    List* values = ListInit();
    List* dimtem = ListInit();
    pVarsValue Vars = malloc(sizeof(pVarsValue));
    if (dimcount != 0)
    {//数组
        int sum = 1;
        for (size_t i = 0; i < dimcount; i++)
        {
            ListPushBack(dimtem, dim[i]);
            sum = sum * dim[i];
        }
        //越界检测用dim
        //1220不初始化数，只存放维度信息//1224存放0
        //符号表不用value3.4
        //注释掉报错？
        if(-1 != dim[0])
        {
            for (size_t i = 0; i < sum; i++)
            {
                ListPushBack(values, 0);
            }
        }
        
        
    }
    else
    {//非数组
        ListPushBack(dimtem, 0);
        ListPushBack(values, 0);
    }
    

    Vars->attr1 = attr1;
    Vars->attr2 = attr2;
    Vars->dim = dimtem;
    Vars->values = values;
    return Vars;
}

//获取失败的情况？用指针？
bool getVarsValue(pFuncValue self, char name[], int dim[], int* num)
{
    pVarsValue val = HashMapGet(self->Vars, name);

    //获取该数字在一维数组中的坐标
    unsigned int dimcount = ListSize(val->dim);
    
    void * getnum;
    int *pnumtem;
    int numtem;
    for (size_t i = 0; i < dimcount; i++)
    {
        ListGetAt(val->dim, i, &getnum);
        pnumtem = getnum;
        numtem = pnumtem;
        for (size_t j = i + 1; j < dimcount; j++)
        {
           dim[j] = (dim[j]) * numtem;
        }
    }
    int idx = 0;
    for (size_t i = 0; i < dimcount; i++)
    {
        int tem = dim[i];
        idx = idx + dim[i];
    }

    int i = ListGetAt(val->values, idx, &getnum);
    pnumtem = getnum;
    numtem = pnumtem;
    *num = numtem;
    return i;
}

bool changeVarsValue(pFuncValue self, char name[], int dim[], int num)
{
    pVarsValue val = HashMapGet(self->Vars, name);

    unsigned int dimcount = ListSize(val->dim);
    void * getnum;
    int *numtem;
    for (size_t i = 0; i < dimcount; i++)
    {
        ListGetAt(val->dim, i, getnum);
        numtem = getnum;
        int dim_val = *numtem;
        for (size_t j = i + 1; j < dimcount; j++)
        {
            dim[j] = dim[j] * dim_val;
        }
    }
    int idx = 0;
    for (size_t i = 0; i < dimcount; i++)
    {
        idx = idx + dim[i];
    }
    idx = idx + 1;

    int i = ListSetAt(val->values, idx, &num);
    return i;
}

//置入FuncIDName Hash
void insertFuncIDName(int start, char funcname[])
{
    
}

//获取Name
char* getFuncName(int start)
{
    void* get;
    get = HashMapGet(FuncIDName, start);
    return get;
}




//1226
void putinsignal(int funcNO, int attr1, int attr2, int dimnum, int dim[], char name[])
{
    int hashvalue = hash(name);
    pVarsValue varsvalue = initpVarsValue(attr1, attr2, dimnum, dim);
    if (funcNO == 0)
    {
        InsertVars(gloabl, hashvalue, varsvalue);
    }
    else
    {
        char* funcname = getFuncName(funcNO);
        pFuncValue funcvalue = getFuncValue(funcname);
        //pVarsValue varsvalue = (attr1, attr2, dimnum, dim);
        InsertVars(funcvalue, hashvalue, varsvalue);
    }
}



int handleconstexps(past node, int** dim)
{
    int dimcount = 0;
    for (past cur = node; cur != NULL; cur = cur->Ast_union.node.next)
    {
        dimcount++;
    }
    
    int *temdim = malloc(sizeof(int) * dimcount);
    int i = 0;
    for (past cur = node; cur != NULL; cur = cur->Ast_union.node.next)
    {
        temdim[i] = cur->Ast_union.node.left->Ast_union.node.middle->Ast_union.ivalue;
        i++;
    }
    *dim = temdim;
    return dimcount;
}
*/